home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / ace / c / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  16.8 KB  |  723 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: main module **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.      Date: 26th October-30th November, 1st-13th December 1991,
  24.        14th,20th-27th January 1992, 
  25.            2nd-17th, 21st-29th February 1992, 
  26.        1st,13th,14th,22nd,23rd March 1992,
  27.        21st,22nd April 1992,
  28.        2nd,3rd,11th,15th,16th May 1992,
  29.        7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  30.        2nd-8th,14th-19th,26th-29th July 1992,
  31.        1st-3rd,7th,8th,9th August 1992,
  32.        6th,7th,21st,22nd December 1992,
  33.        13th,30th January 1993,
  34.        2nd,6th,11th,14th,15th,28th February 1993,
  35.        7th,24th March 1993,
  36.        6th,13th,14th,30th June 1993,
  37.        1st,10th July 1993,
  38.        5th,26th September 1993,
  39.        25th October 1993,
  40.        15th-18th November 1993,
  41.        26th,27th December 1993,
  42.        2nd,5th,7th,9th,13th,14th January 1994,
  43.        7th,26th,27th February 1994,
  44.        4th,13th,30th April 1994,
  45.        14th May 1994,
  46.        12th,14th,21st,22nd,25th June 1994,
  47.        10th,14th,24th July 1994,
  48.        14th,19th August 1994,
  49.        11th,12th September 1994,
  50.        5th,11th March 1995,
  51.        8th August 1995,
  52.        6th October 1995,
  53.        10th March 1996
  54. */
  55.  
  56. #include "acedef.h"
  57.  
  58. /* externals */
  59. extern    char    *srcfile,*destfile;
  60. extern    int    sym;
  61. extern    int    typ;
  62. extern    int    lev;
  63. extern    int    errors;
  64. extern    char       id[MAXIDSIZE]; 
  65. extern    SYM    *curr_item;
  66. extern    CODE    *curr_code;
  67. extern    BOOL    end_of_source;
  68. extern    FILE    *dest;
  69. extern    int      addr[2]; 
  70. extern    char     exit_sub_name[80];
  71. extern    BOOL     early_exit;
  72. extern    int      exitvalue;
  73. extern    char    *rword[];
  74. extern    BOOL     break_opt;
  75. extern    BOOL    optimise_opt;
  76. extern    BOOL    make_icon;
  77. extern    BOOL    error_log;
  78. extern    BOOL    asm_comments;
  79. extern    BOOL    list_source;
  80. extern    BOOL     wdw_close_opt;
  81. extern    BOOL     module_opt;
  82. extern    BOOL    cli_args;
  83. extern    BOOL     mathffpused;
  84. extern    BOOL     mathtransused;
  85. extern    BOOL     dosused;
  86. extern    BOOL     gfxused;
  87. extern    BOOL     intuitionused;
  88. extern    BOOL     translateused;
  89. extern    BOOL     narratorused;
  90. extern    BOOL    ontimerused;
  91. extern    BOOL    iffused;
  92. extern    BOOL     basdatapresent;
  93. extern    BOOL     readpresent;
  94.  
  95. /* external functions */
  96. char    *version();
  97.  
  98. /* functions */
  99. void block()
  100. {
  101. CODE *link;
  102. SYM  *sub_ptr;
  103. char end_of_sub_name[80],end_of_sub_label[80];
  104. char sub_name[80],sub_label[80],exit_sub_label[80];
  105. char xdef_name[80];
  106. char bytes[40],buf[40];
  107. int  subprog;
  108. int  sub_type,def_expr_type;
  109.  
  110.  while (!end_of_source)
  111.  {
  112.   if (sym != subsym && sym != defsym) 
  113.    /* ordinary statement */
  114.    statement();
  115.   else
  116.   {
  117.    /************************/
  118.    /* SUBprogram or DEF FN */
  119.    /************************/
  120.    subprog = sym;
  121.    insymbol();
  122.    
  123.    sub_type = undefined;
  124.  
  125.    /* type identifiers */
  126.    if (sym == shortintsym || sym == longintsym || sym == addresssym ||
  127.        sym == singlesym || sym == stringsym)
  128.    {
  129.     switch(sym)
  130.     {
  131.      case shortintsym : sub_type = shorttype;  break;
  132.      case longintsym  : sub_type = longtype;   break;
  133.      case addresssym  : sub_type = longtype;   break;
  134.      case singlesym   : sub_type = singletype; break;
  135.      case stringsym   : sub_type = stringtype; break;
  136.     }
  137.     insymbol();
  138.    }
  139.  
  140.    if (sym != ident) _error(32);
  141.    else
  142.    { 
  143.     /* get name of subprogram and prefix _SUB_ to it */
  144.     strcpy(sub_name,"_SUB_");
  145.     strcat(sub_name,id);
  146.  
  147.     if (!exist(sub_name,subprogram)) 
  148.     {
  149.       if (sub_type == undefined) sub_type = typ;
  150.       enter(sub_name,sub_type,subprogram,0);  /* new SUB */
  151.       curr_item->decl=subdecl;
  152.     }
  153.     else
  154.        if ((exist(sub_name,subprogram)) && (curr_item->decl == fwdref))
  155.           curr_item->decl=subdecl;
  156.        else 
  157.            _error(33); /* already exists */
  158.  
  159.     sub_ptr=curr_item; /* pointer to sub info' */
  160.  
  161.     turn_event_off(sub_name);   /* see event.c */
  162.  
  163.     /* exit point name & label */
  164.     strcpy(exit_sub_name,"_EXIT");
  165.     strcat(exit_sub_name,sub_name);
  166.     strcpy(exit_sub_label,exit_sub_name);
  167.     strcat(exit_sub_label,":\0");
  168.  
  169.     /* prepare for level ONE */
  170.     lev=ONE; 
  171.     addr[lev]=0; 
  172.     new_symtab();
  173.     make_label(end_of_sub_name,end_of_sub_label);
  174.     gen("jmp",end_of_sub_name,"  ");
  175.  
  176.     /* subprogram label -> _SUB_ prefix to make it unique */
  177.     strcpy(sub_label,sub_name);
  178.     strcat(sub_label,":\0");
  179.     gen(sub_label,"  ","  ");
  180.  
  181.     /* all SUBs need link instruction -- add # of bytes later */
  182.     gen("link","a5","  ");
  183.     link=curr_code;
  184.  
  185.     /* parse formal parameter list */
  186.     sub_params(sub_ptr);
  187.  
  188.     /* make this subprogram externally visible? */
  189.     if (sym == externalsym)
  190.     {
  191.     insymbol();
  192.     strcpy(xdef_name,sub_name);
  193.     xdef_name[0] = '*';  /* signal that this is an XDEF */
  194.     enter_XREF(xdef_name);
  195.     }
  196.  
  197.     /* 
  198.     ** Pass function (SUB) values via d0 for ALL subprograms 
  199.     ** in a module since there is no link using A4 for modules.
  200.     */
  201.     if (module_opt)
  202.     sub_ptr->address = extfunc;  /* This has a numeric value of 3004:
  203.                     hopefully large enough to avoid
  204.                     clashes with real stack offsets. */
  205.     
  206.     /* SUB or DEF FN code? */
  207.     if (subprog == subsym)
  208.     {
  209.       while ((sym != endsym) && (!end_of_source)) 
  210.       {
  211.        if (sym == sharedsym) parse_shared_vars();
  212.        if ((sym != endsym) && (!end_of_source)) statement();
  213.       }
  214.  
  215.       if (end_of_source) _error(34);  /* END SUB expected */
  216.  
  217.       if (sym == endsym) 
  218.       {
  219.        insymbol();
  220.        if (sym != subsym) _error(35); 
  221.        insymbol(); 
  222.       }
  223.     }
  224.     else
  225.     {
  226.         /* DEF FN code */
  227.     if (sym != equal)
  228.        _error(5);
  229.     else
  230.     {
  231.       insymbol();
  232.            def_expr_type = expr();
  233.       if (assign_coerce(sub_type,def_expr_type) != sub_type)
  234.          _error(4);
  235.       else
  236.       if (sub_type == shorttype)
  237.           gen("move.w","(sp)+","d0");
  238.       else
  239.         gen("move.l","(sp)+","d0");
  240.  
  241.         /* change object from SUB to DEF FN */
  242.       sub_ptr->object = definedfunc;
  243.     }
  244.     }
  245.  
  246.     /* establish size of stack frame */
  247.     if (addr[lev] == 0)
  248.        strcpy(bytes,"#\0");
  249.     else
  250.        strcpy(bytes,"#-");     
  251.     itoa(addr[lev],buf,10);   
  252.     strcat(bytes,buf);   
  253.     change(link,"link","a5",bytes);  
  254.  
  255.     /* exit code */
  256.     if (subprog == subsym) gen(exit_sub_label,"  ","  ");
  257.     gen("unlk","a5","  ");
  258.     gen("rts","  ","  ");
  259.     gen(end_of_sub_label,"  ","  ");
  260.  
  261.     kill_symtab();
  262.     lev=ZERO;
  263.    } 
  264.   }
  265.  }
  266. }
  267.  
  268. void parse()
  269. {
  270.  lev=ZERO;
  271.  addr[lev]=0;
  272.  new_symtab();
  273.  create_lists();
  274.   
  275.  insymbol();
  276.  block();
  277.  
  278.  undef_label_check();
  279.  kill_symtab();
  280. }
  281.  
  282. void compile(source_name,dest_name)
  283. char *source_name,*dest_name;
  284. {
  285. char buf[40],bytes[40],icon_name[MAXSTRLEN];
  286. FILE *icon_src,*icon_dest;
  287. int  cc;
  288.  
  289.  /* 
  290.  ** Parse the source file producing XREFs, code, data, 
  291.  ** bss & basdata segments.
  292.  */
  293.  parse();
  294.  
  295.  /* optimise? */
  296.  if (optimise_opt && !early_exit) optimise();
  297.  
  298.  if (!module_opt)
  299.  {
  300.    /* startup xrefs for startup.lib */
  301.    enter_XREF("_startup");
  302.    enter_XREF("_cleanup");
  303.  
  304.    /* command line argument xref */
  305.    if (cli_args) enter_XREF("_parse_cli_args");
  306.  
  307.    if (translateused)
  308.    {
  309.     enter_XREF("_opentranslator");
  310.     enter_XREF("_closetranslator");
  311.    }
  312.  
  313.    if (mathffpused)
  314.    {
  315.     enter_XREF("_openmathffp");
  316.     enter_XREF("_closemathffp");
  317.    }
  318.  
  319.    if (mathtransused)
  320.    {
  321.     enter_XREF("_openmathtrans");
  322.     enter_XREF("_closemathtrans");
  323.    }
  324.  
  325.    if (gfxused)
  326.    {
  327.     enter_XREF("_opengfx");
  328.     enter_XREF("_closegfx");
  329.     enter_XREF("_openintuition");
  330.     enter_XREF("_closeintuition");
  331.    }
  332.  
  333.    if (intuitionused)
  334.    {
  335.     enter_XREF("_openintuition");
  336.     enter_XREF("_closeintuition");
  337.    }
  338.  
  339.    if (iffused)
  340.    {
  341.     enter_XREF("_create_ILBMLib");
  342.     enter_XREF("_remove_ILBMLib");
  343.    }
  344.  
  345.    enter_XREF("_starterr");
  346.  
  347.    /*
  348.    ** A module may need to jump to _EXIT_PROG so
  349.    ** make this label externally referenceable (* = XDEF).
  350.    */
  351.    enter_XREF("*EXIT_PROG");
  352.  
  353.    if (ontimerused) enter_XREF("_ontimerstart");
  354.  
  355.    /*
  356.    ** Always call this in case a db.lib function 
  357.    ** allocates memory via alloc(). This also takes
  358.    ** care of the use of ALLOC by an ACE program.
  359.    ** To do this we always need to externally 
  360.    ** reference the free_alloc() function.
  361.    */
  362.    enter_XREF("_free_alloc");
  363.  }
  364.  else
  365.  {
  366.    /*
  367.    ** Current module may need to jump to _EXIT_PROG, so externally reference it.
  368.    */
  369.     enter_XREF("_EXIT_PROG");
  370.  }
  371.   
  372.  /* DATA statements? */
  373.  if (basdatapresent) enter_BSS("_dataptr:","ds.l 1");
  374.  if ((readpresent) && (!basdatapresent)) _error(25); 
  375.  
  376.  /* ------------------------------------------------- */
  377.  /* create A68K compatible 68000 assembly source file */
  378.  /* ------------------------------------------------- */
  379.  
  380.  if (!early_exit) 
  381.     printf("\ncreating %s\n",dest_name);
  382.  else
  383.     printf("\nfreeing code list...\n");
  384.  
  385.  if (!early_exit) write_xrefs();
  386.  
  387.  /* startup code */
  388.  fprintf(dest,"\n\tSECTION code,CODE\n\n");
  389.  
  390.  if (!module_opt)
  391.  {
  392.    /* 
  393.    ** Check for Wb start BEFORE DOING ANYTHING ELSE! 
  394.    ** This also always opens dos.library and stores 
  395.    ** CLI argument data. 
  396.    */
  397.    fprintf(dest,"\tjsr\t_startup\n");
  398.    fprintf(dest,"\tcmpi.b\t#1,_starterr\n"); /* see _startup in startup.lib */
  399.    fprintf(dest,"\tbne.s\t_START_PROG\n");
  400.    fprintf(dest,"\trts\n");
  401.    fprintf(dest,"_START_PROG:\n");
  402.  
  403.    /* storage for initial stack pointer */
  404.    enter_BSS("_initialSP:","ds.l 1");
  405.    fprintf(dest,"\tmove.l\tsp,_initialSP\n"); /* save task's stack pointer */
  406.  
  407.    fprintf(dest,"\tmovem.l\td1-d7/a0-a6,-(sp)\n"); /* save initial registers */
  408.  
  409.    if (cli_args) 
  410.       fprintf(dest,"\tjsr\t_parse_cli_args\n"); /* get CLI arguments */
  411.  
  412.    if (translateused) 
  413.    {
  414.     fprintf(dest,"\tjsr\t_opentranslator\n");
  415.     fprintf(dest,"\tcmpi.b\t#1,_starterr\n");
  416.     fprintf(dest,"\tbne.s\t_translate_ok\n");
  417.     fprintf(dest,"\tjmp\t_ABORT_PROG\n");
  418.     fprintf(dest,"_translate_ok:\n");
  419.    }   
  420.  
  421.    if (mathffpused) 
  422.    {
  423.     fprintf(dest,"\tjsr\t_openmathffp\n");
  424.     fprintf(dest,"\tcmpi.b\t#1,_starterr\n");
  425.     fprintf(dest,"\tbne.s\t_mathffp_ok\n");
  426.     fprintf(dest,"\tjmp\t_ABORT_PROG\n");
  427.     fprintf(dest,"_mathffp_ok:\n");
  428.    }   
  429.  
  430.    if (mathtransused) 
  431.    {
  432.     fprintf(dest,"\tjsr\t_openmathtrans\n"); 
  433.     fprintf(dest,"\tcmpi.b\t#1,_starterr\n");
  434.     fprintf(dest,"\tbne.s\t_mathtrans_ok\n");
  435.     fprintf(dest,"\tjmp\t_ABORT_PROG\n");
  436.     fprintf(dest,"_mathtrans_ok:\n");
  437.    }   
  438.  
  439.    if (intuitionused && !gfxused) 
  440.    {
  441.     fprintf(dest,"\tjsr\t_openintuition\n");   
  442.     fprintf(dest,"\tcmpi.b\t#1,_starterr\n");
  443.     fprintf(dest,"\tbne.s\t_intuition_ok\n");
  444.     fprintf(dest,"\tjmp\t_ABORT_PROG\n");
  445.     fprintf(dest,"_intuition_ok:\n");
  446.    }   
  447.  
  448.    if (gfxused)
  449.    {
  450.     /* open intuition.library */
  451.     fprintf(dest,"\tjsr\t_openintuition\n");    
  452.     fprintf(dest,"\tcmpi.b\t#1,_starterr\n");
  453.     fprintf(dest,"\tbne.s\t_intuition_ok\n");
  454.     fprintf(dest,"\tjmp\t_ABORT_PROG\n");
  455.     fprintf(dest,"_intuition_ok:\n");
  456.  
  457.     /* open graphics.library */
  458.     fprintf(dest,"\tjsr\t_opengfx\n");  
  459.     fprintf(dest,"\tcmpi.b\t#1,_starterr\n");
  460.     fprintf(dest,"\tbne.s\t_gfx_ok\n");
  461.     fprintf(dest,"\tjmp\t_ABORT_PROG\n");
  462.     fprintf(dest,"_gfx_ok:\n");
  463.    }   
  464.  
  465.    /* create temporary ILBM.library */
  466.    if (iffused) fprintf(dest,"\tjsr\t_create_ILBMLib\n");
  467.  
  468.    /* get timer event trapping start time */
  469.    if (ontimerused) fprintf(dest,"\tjsr\t_ontimerstart\n");
  470.  
  471.    /* size of stack frame */ 
  472.    if (addr[lev] == 0)
  473.       strcpy(bytes,"#\0");
  474.    else
  475.       strcpy(bytes,"#-");     
  476.    itoa(addr[lev],buf,10);   
  477.    strcat(bytes,buf);     
  478.  
  479.    /* create stack frame */
  480.    fprintf(dest,"\tlink\ta4,%s\n\n",bytes); 
  481.  
  482.    /* initialise global DATA pointer */
  483.    if (basdatapresent) fprintf(dest,"\tmove.l\t#_BASICdata,_dataptr\n");
  484.  }
  485.  
  486.  /* write code & kill code list */
  487.  kill_code();
  488.  
  489.  if (!module_opt)
  490.  {
  491.    /* exiting code */
  492.    fprintf(dest,"\n_EXIT_PROG:\n");
  493.  
  494.    fprintf(dest,"\tunlk\ta4\n");
  495.  
  496.    /* 
  497.    ** Programs which abort should cleanup libraries, free allocated memory
  498.    ** and possibly reply to a Wb startup message. 
  499.    */
  500.    if (intuitionused || gfxused || mathffpused || mathtransused ||
  501.        translateused) 
  502.       fprintf(dest,"_ABORT_PROG:\n");
  503.  
  504.    /* Free memory allocated via ALLOC and db.lib calls to alloc(). */
  505.    fprintf(dest,"\tjsr\t_free_alloc\n");
  506.  
  507.    /* close libraries */
  508.    if (gfxused) 
  509.    {
  510.     fprintf(dest,"\tjsr\t_closegfx\n");
  511.     fprintf(dest,"\tjsr\t_closeintuition\n");
  512.    }
  513.    if (narratorused) fprintf(dest,"\tjsr\t_cleanup_async_speech\n");
  514.    if (intuitionused && !gfxused) fprintf(dest,"\tjsr\t_closeintuition\n");
  515.    if (mathtransused) fprintf(dest,"\tjsr\t_closemathtrans\n");
  516.    if (mathffpused) fprintf(dest,"\tjsr\t_closemathffp\n");
  517.    if (translateused) fprintf(dest,"\tjsr\t_closetranslator\n");
  518.  
  519.    /* delete temporary ILBM.library */
  520.    if (iffused) fprintf(dest,"\tjsr\t_remove_ILBMLib\n");
  521.  
  522.    /* restore registers */
  523.    fprintf(dest,"\tmovem.l\t(sp)+,d1-d7/a0-a6\n");
  524.  
  525.    /* restore initial stack pointer */
  526.    fprintf(dest,"\tmove.l\t_initialSP,sp\n");
  527.  
  528.    /* 
  529.    ** Close dos.library and reply to Wb message
  530.    ** as the LAST THING DONE before rts'ing.
  531.    */
  532.    fprintf(dest,"\tjsr\t_cleanup\n");
  533.  
  534.    /* return */
  535.    fprintf(dest,"\n\trts\n");
  536.  }
  537.  
  538.  if (!early_exit)
  539.  {
  540.    write_data();
  541.    write_basdata();  
  542.    write_bss();
  543.  }
  544.  
  545.  fprintf(dest,"\n\tEND\n");
  546.  
  547.  /* errors? */
  548.  if (errors > 0) putchar('\n');
  549.  
  550.  printf("%s compiled ",source_name);
  551.  
  552.  if (errors == 0)    
  553.     printf("with no errors.\n");
  554.  else
  555.  {
  556.   exitvalue=10; /* set ERROR for bas script */
  557.   printf("with %d ",errors);
  558.   if (errors > 1) printf("errors.\n");
  559.   else printf("error.\n");
  560.  }
  561.  
  562.  /* make icon? */
  563.  if (make_icon && !early_exit)
  564.  {
  565.   if ((icon_src = fopen("ACE:icons/exe.info","r")) == NULL)
  566.     puts("can't open ACE:icons/exe.info for reading."); 
  567.   else
  568.   {
  569.    cc=0; while(source_name[cc] != '.') cc++; 
  570.    source_name[cc] = '\0';   
  571.    sprintf(icon_name,"%s.info",source_name);
  572.    if ((icon_dest = fopen(icon_name,"w")) == NULL)
  573.       printf("can't open %s.info for writing.\n",source_name);
  574.    else
  575.    {
  576.     while (!feof(icon_src)) fputc(fgetc(icon_src),icon_dest);
  577.     fclose(icon_dest);
  578.     fclose(icon_src);
  579.     puts("icon created.");
  580.    }
  581.   }
  582.  }
  583. }
  584.  
  585. void show_title()
  586. {
  587.  printf("ACE Amiga BASIC Compiler version %s, copyright ",version());
  588.  putchar(169);  /* copyright symbol */
  589.  puts(" 1991-1996 David Benn.");
  590. }
  591.  
  592. void usage()
  593. {
  594.  printf("usage: ACE [words | -bcEilmOw] <sourcefile>[.b[as]]\n");
  595. }
  596.  
  597. BOOL check_options(opt)
  598. char *opt;
  599. {
  600. BOOL legalopt=TRUE;
  601.  
  602.  if (*opt != '-') return(FALSE);
  603.  /* extract the options */
  604.  opt++;
  605.  if (*opt == '\0') 
  606.         legalopt=FALSE;
  607.  else
  608.  while ((*opt != '\0') && (legalopt)) 
  609.  {
  610.   if (*opt == 'b') break_opt=TRUE; 
  611.   else
  612.   if (*opt == 'O') optimise_opt=TRUE; 
  613.   else
  614.   if (*opt == 'i') make_icon=TRUE; 
  615.   else
  616.   if (*opt == 'E') error_log=TRUE;
  617.   else
  618.   if (*opt == 'c') asm_comments=TRUE;
  619.   else
  620.   if (*opt == 'l') list_source=TRUE;
  621.   else
  622.   if (*opt == 'm') module_opt=TRUE;
  623.   else
  624.   if (*opt == 'w') wdw_close_opt=TRUE;
  625.   else
  626.      legalopt=FALSE;
  627.   opt++;
  628.  }
  629.  
  630.  return(legalopt);
  631. }
  632.  
  633. void ctrl_c_break_test()
  634. {
  635.     if (SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) 
  636.     {
  637.         puts("\n*** Break: ACE terminating.");
  638.         exit(5);
  639.     }
  640. }
  641.  
  642. void dump_reserved_words()
  643. {
  644. int i;
  645.  
  646.  printf("\nAmigaBASIC RESERVED WORDS: %ld\n\n",(xorsym-abssym)+1);
  647.  
  648.  for (i=abssym;i<=xorsym;i++) 
  649.  {
  650.      printf("%s\n",rword[i]);
  651.     ctrl_c_break_test();    
  652.  }
  653.  
  654.  printf("\nACE-SPECIFIC RESERVED WORDS: %ld\n\n",(ycorsym-addresssym)+1);
  655.  
  656.  for (i=addresssym;i<=ycorsym;i++) 
  657.  {
  658.      printf("%s\n",rword[i]);
  659.     ctrl_c_break_test();    
  660.  }
  661. }
  662.   
  663. void main(argc,argv)
  664. int  argc;
  665. char *argv[];
  666. {
  667. char *tmparg;
  668.  
  669.  show_title();
  670.   
  671.  /* 
  672.  ** - get args and compiler switches.
  673.  ** - open source and destination files. 
  674.  */ 
  675.  if ((argc == 1) || (argc > 3)) 
  676.     { usage(); exit(10); } /* arg count mismatch */
  677.  
  678.  /* send reserved words to stdout then quit? */
  679.  tmparg = (char *)malloc(strlen(argv[1])+1);
  680.  if (tmparg == NULL) 
  681.  {
  682.     puts("Unable to allocate temporary argument buffer!");
  683.      exit(10);
  684.  }
  685.  else   
  686.  {
  687.     strcpy(tmparg,argv[1]);
  688.  
  689.      if (strcmp(strupr(tmparg),"WORDS") == 0)
  690.      {
  691.         dump_reserved_words();
  692.         if (tmparg) free(tmparg);
  693.          exit(0);
  694.      }
  695.     else
  696.         if (tmparg) free(tmparg);
  697.  }
  698.  
  699.  open_shared_libs();
  700.  
  701.  /* 
  702.  ** compile program 
  703.  */
  704.  if (argc == 2) 
  705.  {
  706.     /* source file, no options */
  707.     open_files(argv[1]);
  708.     setup();
  709.     compile(srcfile,destfile); 
  710.  }
  711.  else 
  712.  {
  713.     /* options plus source file */
  714.     if (!check_options(argv[1])) 
  715.        { usage(); close_shared_libs(); exit(10); } /* illegal options */  
  716.     open_files(argv[2]);  
  717.     setup();
  718.     compile(srcfile,destfile);
  719.  }
  720.  
  721.  cleanup();
  722. }
  723.